#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdint.h>

// UDP 传递给低碳平台的数据结构体定义

typedef struct {
    uint16_t datatype; // 1公共数据， 2 单个列车数据  3 控制发送数据
    uint16_t blank; // 列车ID
    uint16_t datetime;  //时间戳
    uint16_t mode; //是否节能模式 0 非节能， 1 节能
    uint16_t en_driver_tmc1; //司机室能耗
    uint16_t en_passenger_tmc1; //乘客室能耗
    uint16_t en_passenger_mp1; //乘客室能耗
    uint16_t en_passenger_mp2; //乘客室能耗
    uint16_t en_driver_tmc2; //司机室能耗
    uint16_t en_passenger_tmc2; //乘客室能耗
    uint16_t en_all; //列车总能耗
    uint16_t weight_a1; //A1车厢重量
    uint16_t weight_b1; //B1车厢重量
    uint16_t weight_b2; //B2车厢重量
    uint16_t weight_a2; //A2车厢重量
} global_train_data;

typedef struct {
    uint16_t datatype; // 1公共数据， 2 单个列车数据  3 控制发送数据
    uint16_t sn; // 列车代号
    uint16_t datetime;  //时间戳

    uint8_t target_temp; // 目标温度
    uint8_t driver_temp; // 司机室目标温度

    uint8_t passenger_temp; // 乘客室回风温度
    uint8_t driver_return_temp; // 司机室回风温度

    uint8_t passenger_new_temp; // 乘客室新风温度
    uint8_t driver_new_temp; // 司机室新风温度

    uint8_t blank1;
    uint8_t blank2;

    uint16_t mode_data;  //模式数据
    uint16_t enpressor_data;  //压缩机数据
    uint16_t new_wind_data;  //新风开度数据
    uint16_t new_wind_data2;  //新风开度数据2

    uint16_t blank3;  //空位
    uint16_t blank4;  //空位
    uint16_t blank5;  //空位
    uint16_t blank6;  //空位
    uint16_t blank7;  //空位
} single_train_data;

typedef struct {
    uint16_t datatype; // 1公共数据， 2 单个列车数据  3 控制发送数据
    uint16_t sn; // 列车代号
    uint16_t datetime;  //时间戳
    uint8_t target_temp; //客室弥补表温度
    uint8_t blank;

    uint16_t blank3;  //空位
    uint16_t blank4;  //空位
    uint16_t blank5;  //空位
    uint16_t blank6;  //空位
    uint16_t blank7;  //空位

    uint8_t new_wind_data; //新风阀开度指令
    uint8_t blank2;

    uint16_t blank8;  //空位
    uint16_t blank9;  //空位
    uint16_t blank10;  //空位
    uint16_t blank11;  //空位
    uint16_t blank12;  //空位
} single_train_order_data;

// 构造虚拟数据的函数
void fill_global_train_data(global_train_data *data) {
    data->datatype = 1;
    data->blank = 1001;
    data->datetime = 0x1234;
    data->mode = 1;
    data->en_driver_tmc1 = 120;
    data->en_passenger_tmc1 = 300;
    data->en_passenger_mp1 = 200;
    data->en_passenger_mp2 = 210;
    data->en_driver_tmc2 = 130;
    data->en_passenger_tmc2 = 310;
    data->en_all = 1270;
    data->weight_a1 = 40000;
    data->weight_b1 = 41000;
    data->weight_b2 = 42000;
    data->weight_a2 = 43000;
}

void fill_single_train_data(single_train_data *data) {
    data->datatype = 2;
    data->sn = 2002;
    data->datetime = 0x5678;
    data->target_temp = 23;
    data->driver_temp = 25;
    data->passenger_temp = 26;
    data->driver_return_temp = 27;
    data->passenger_new_temp = 28;
    data->driver_new_temp = 29;
    data->blank1 = 0;
    data->blank2 = 0;
    data->mode_data = 1;
    data->enpressor_data = 2;
    data->new_wind_data = 50;
    data->new_wind_data2 = 51;
    data->blank3 = 0;
    data->blank4 = 0;
    data->blank5 = 0;
    data->blank6 = 0;
    data->blank7 = 0;
}

void fill_single_train_order_data(single_train_order_data *data) {
    data->datatype = 3;
    data->sn = 3003;
    data->datetime = 0x9abc;
    data->target_temp = 22;
    data->blank = 0;
    data->blank3 = 0;
    data->blank4 = 0;
    data->blank5 = 0;
    data->blank6 = 0;
    data->blank7 = 0;
    data->new_wind_data = 60;
    data->blank2 = 0;
    data->blank8 = 0;
    data->blank9 = 0;
    data->blank10 = 0;
    data->blank11 = 0;
    data->blank12 = 0;
}

int main() {
    // 目标IP和端口
    const char *target_ip = "127.0.0.1";
    int target_port = 12345;

    int sockfd;
    struct sockaddr_in dest_addr;

    // 创建UDP套接字
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("socket 创建失败");
        return 1;
    }

    memset(&dest_addr, 0, sizeof(dest_addr));
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(target_port);
    if (inet_pton(AF_INET, target_ip, &dest_addr.sin_addr) <= 0) {
        perror("无效的IP地址");
        close(sockfd);
        return 1;
    }

    // 构造三种结构体的虚拟数据
    global_train_data g_data;
    single_train_data s_data;
    single_train_order_data o_data;

    fill_global_train_data(&g_data);
    fill_single_train_data(&s_data);
    fill_single_train_order_data(&o_data);

    // 发送 global_train_data
    ssize_t sent_bytes = sendto(sockfd, &g_data, sizeof(g_data), 0,
                                (struct sockaddr *)&dest_addr, sizeof(dest_addr));
    if (sent_bytes < 0) {
        perror("发送 global_train_data 失败");
    } else {
        printf("已发送 global_train_data (%zd 字节) 到 %s:%d\n", sent_bytes, target_ip, target_port);
    }

    // 发送 single_train_data
    sent_bytes = sendto(sockfd, &s_data, sizeof(s_data), 0,
                        (struct sockaddr *)&dest_addr, sizeof(dest_addr));
    if (sent_bytes < 0) {
        perror("发送 single_train_data 失败");
    } else {
        printf("已发送 single_train_data (%zd 字节) 到 %s:%d\n", sent_bytes, target_ip, target_port);
    }

    // 发送 single_train_order_data
    sent_bytes = sendto(sockfd, &o_data, sizeof(o_data), 0,
                        (struct sockaddr *)&dest_addr, sizeof(dest_addr));
    if (sent_bytes < 0) {
        perror("发送 single_train_order_data 失败");
    } else {
        printf("已发送 single_train_order_data (%zd 字节) 到 %s:%d\n", sent_bytes, target_ip, target_port);
    }

    close(sockfd);
    return 0;
}
